package org.testis.gui.mvc.view.testdesign;

import org.testis.gui.mvc.view.*;
import org.testis.gui.mvc.controller.testdesign.SearchController;
import org.testis.gui.mvc.controller.TestDesignControllerList;
import org.testis.gui.mvc.utilities.MyTreeRenderer;
import org.testis.gui.mvc.utilities.TristateLabelTreeNodeEditor;
import org.testis.gui.mvc.utilities.TristateLabelTreeNodeRenderer;
import org.testis.utils.tree.DefaultMutableLabelNode;
import org.testis.utils.tree.MyDefaultMutableTreeNode;
import java.beans.PropertyChangeEvent;
import java.awt.Frame;
import java.awt.event.WindowListener;
import java.util.Enumeration;
import java.util.LinkedList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.testis.orm.classes.T_test_label;
import org.testis.orm.refinedclasses.LabelFilterRefined;
import org.testis.orm.refinedclasses.TestDesignTreeNode;
import org.testis.utils.tree.TristateLabelTreeNode;
import org.testis.utils.tree.TristateState;

/**
 *
 * @author Cahit Emir Erel
 */
public class SearchView2 extends AtofBaseDialog implements AbstractViewPanel {

    private static final long serialVersionUID = 74234394L;
    private MyDefaultMutableTreeNode m_jDesignTreeRoot;
    public static final String SELECT_LABEL_REGEX = "(?=.*\\blabel\\b)";
    public static final String NOT_SELECT_LABEL_REGEX = "(?!.*\\blabel\\b)";

    public SearchView2(Frame parent,
            boolean modal) {
        super(parent, modal);
        m_jDesignTreeRoot = new MyDefaultMutableTreeNode(false);
        initComponents();
//        initLabelCombobox();
        initLabelsPanel();
        initLabelTree();
        jSplitPane1.setOneTouchExpandable(true);
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        leftPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        testDesignTree = new JTree(m_jDesignTreeRoot);
        rightPanel = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        propertyTextPane = new javax.swing.JTextPane();
        operatorComboBox = new javax.swing.JComboBox();
        okButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        cancelButton = new javax.swing.JButton();
        addButton = new javax.swing.JButton();
        selectButton = new javax.swing.JButton();
        jCheckBox1 = new javax.swing.JCheckBox();
        jScrollPane2 = new javax.swing.JScrollPane();
        queryItemList = new javax.swing.JList();
        removeButton = new javax.swing.JButton();
        jScrollPane5 = new javax.swing.JScrollPane();
        labelTree = new javax.swing.JTree();
        saveButton = new javax.swing.JButton();
        loadFilterButton = new javax.swing.JButton();
        filterComboBox = new javax.swing.JComboBox();
        jSeparator2 = new javax.swing.JSeparator();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Case Filter");
        setModal(true);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        jSplitPane1.setDividerLocation(250);

        leftPanel.setMinimumSize(new java.awt.Dimension(200, 0));

        testDesignTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        testDesignTree.putClientProperty("JTree.lineStyle", "Angled");
        testDesignTree.setCellRenderer(new MyTreeRenderer());
        testDesignTree.setExpandsSelectedPaths(false);
        testDesignTree.setRootVisible(false);
        testDesignTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                testDesignTreeMouseClicked(evt);
            }
        });
        testDesignTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                testDesignTreeValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(testDesignTree);

        javax.swing.GroupLayout leftPanelLayout = new javax.swing.GroupLayout(leftPanel);
        leftPanel.setLayout(leftPanelLayout);
        leftPanelLayout.setHorizontalGroup(
            leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
        );
        leftPanelLayout.setVerticalGroup(
            leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE)
        );

        jSplitPane1.setLeftComponent(leftPanel);

        propertyTextPane.setEditable(false);
        jScrollPane3.setViewportView(propertyTextPane);

        operatorComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Select", "Not Select" }));
        operatorComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                operatorComboBoxActionPerformed(evt);
            }
        });

        okButton.setText("Ok");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        addButton.setText("Add");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        selectButton.setText("Select");
        selectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectButtonActionPerformed(evt);
            }
        });

        jCheckBox1.setSelected(true);
        jCheckBox1.setText("Apply selection to Main Test Design Tree");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        queryItemList.setModel(new DefaultListModel());
        queryItemList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                queryItemListValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(queryItemList);

        removeButton.setText("Remove");
        removeButton.setEnabled(false);
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });

        jScrollPane5.setViewportView(labelTree);

        saveButton.setText("Save");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        loadFilterButton.setText("Load");
        loadFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadFilterButtonActionPerformed(evt);
            }
        });

        filterComboBox.setModel(new DefaultComboBoxModel());

        javax.swing.GroupLayout rightPanelLayout = new javax.swing.GroupLayout(rightPanel);
        rightPanel.setLayout(rightPanelLayout);
        rightPanelLayout.setHorizontalGroup(
            rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(rightPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addGroup(rightPanelLayout.createSequentialGroup()
                        .addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jCheckBox1))
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, rightPanelLayout.createSequentialGroup()
                        .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(rightPanelLayout.createSequentialGroup()
                        .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(rightPanelLayout.createSequentialGroup()
                                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(operatorComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(filterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(loadFilterButton)
                                    .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(saveButton)
                            .addComponent(removeButton)))
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE))
                .addContainerGap())
        );

        rightPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {addButton, loadFilterButton, removeButton, saveButton});

        rightPanelLayout.setVerticalGroup(
            rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(rightPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(13, 13, 13)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 11, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(filterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(loadFilterButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(operatorComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(rightPanelLayout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(selectButton)
                            .addComponent(jCheckBox1)))
                    .addGroup(rightPanelLayout.createSequentialGroup()
                        .addComponent(removeButton)
                        .addGap(11, 11, 11)
                        .addComponent(saveButton)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(okButton))
                .addContainerGap(35, Short.MAX_VALUE))
        );

        jSplitPane1.setRightComponent(rightPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 831, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 635, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void initLabelsPanel() {
        /*
        TitledBorder border = new TitledBorder("Labels");
        labelsPanel.setBorder(border);
        labelsPanel.setLayout(new GridLayout(0, 2, 5, 5));
        String[] labelList = TestDesignControllerList.newInstance().getTestCaseController().getLabelList();
        for (int i = 0; i < labelList.length; i++) {
        TristateCheckBox tristateBox = new TristateCheckBox(labelList[i]);
        labelsPanel.add(tristateBox);
        }*/
    }

//    private int mouseX;
//    private int mouseY;
//    private Component component;
    private void testDesignTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_testDesignTreeMouseClicked

        MyDefaultMutableTreeNode node =
                (MyDefaultMutableTreeNode) testDesignTree.getLastSelectedPathComponent();
        int x = evt.getX();
        int y = evt.getY();
        int row = testDesignTree.getRowForLocation(x, y);
        TreePath path = testDesignTree.getPathForRow(row);
        if (path != null && node != null) {
            if (evt.getX() > testDesignTree.getPathBounds(path).x + 21) {
                return;
            }
            boolean isSelected = !(node.isSelected());
            //node.setSelected(isSelected);
            if (node.hasCheckBox()) {
                node.setSelected(isSelected);
                node.setSelectedSingle(isSelected);
                if (isSelected) {
                    testDesignTree.expandPath(path);
                } else {
                    testDesignTree.collapsePath(path);
                }
            }
            testDesignTree.revalidate();
            testDesignTree.repaint();
            TestDesignControllerList.newInstance().getSearchController().operationSelectDesignPart(node);
        }
}//GEN-LAST:event_testDesignTreeMouseClicked

    private void testDesignTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_testDesignTreeValueChanged

        MyDefaultMutableTreeNode node = (MyDefaultMutableTreeNode) testDesignTree.getLastSelectedPathComponent();
        TestDesignControllerList.newInstance().getSearchController().operationSelectDesignPart(node);
}//GEN-LAST:event_testDesignTreeValueChanged

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        WindowListener[] listeners = getWindowListeners();
        for (int i = 0; i < listeners.length; i++) {
            this.removeWindowListener(listeners[i]);
        }
        setEnabled(false);
        TestDesignControllerList.newInstance().getSearchController().operationCloseWindow();
    }//GEN-LAST:event_formWindowClosed

    private void operatorComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_operatorComboBoxActionPerformed
    {//GEN-HEADEREND:event_operatorComboBoxActionPerformed

        /*
        if (labelComboBox.getSelectedItem().equals("") && operatorComboBox.getSelectedItem().equals("")) {
        addButton.setEnabled(false);
        } else {
        addButton.setEnabled(true);
        }
         */
    }//GEN-LAST:event_operatorComboBoxActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_addButtonActionPerformed
    {//GEN-HEADEREND:event_addButtonActionPerformed
        String statement = getLabelSelectionStr();
        if (statement.length() > 0) {
            if (operatorComboBox.getSelectedIndex() == 1) {
                statement = negateStatement(statement);
                operatorComboBox.setSelectedIndex(0);
            }
            ((DefaultListModel) queryItemList.getModel()).addElement(statement);
            TestDesignControllerList.newInstance().getSearchController().operationLoadLabelTreeModel();
        }
    }//GEN-LAST:event_addButtonActionPerformed

    private String negateStatement(String statement) {
        if (statement == null || statement.isEmpty()) {
            return statement;
        }
        String strList[] = statement.split(" AND ");
        StringBuilder sb = new StringBuilder();
        for (String str : strList) {
            if (str.isEmpty()) {
                continue;
            }
            String label;
            if (str.startsWith("!")) {
                label = str.substring(1);
            } else {
                label = "!" + str;
            }
            sb.append(label + " AND ");
        }
        String result = sb.toString().trim();
        if (result.endsWith(" AND")) {
            result = result.substring(0, result.length() - 4).trim();
        }
        return result;
    }

    private void selectButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_selectButtonActionPerformed
    {//GEN-HEADEREND:event_selectButtonActionPerformed
        unSelectAll(m_jDesignTreeRoot);
        testDesignTree.repaint();
        String regex = buildRegex();
//        System.out.println("FULL REGEX:" + regex);
        TestDesignControllerList.newInstance().getSearchController().operationExecRegex(regex);
    }//GEN-LAST:event_selectButtonActionPerformed

    private String buildRegex() {
        StringBuilder sb = new StringBuilder();
        int numberOfStatement = queryItemList.getModel().getSize();
        for (int i = 0; i < numberOfStatement; i++) {
            String statement = (String) queryItemList.getModel().getElementAt(i);
            sb.append(buildRegex(statement));
            sb.append('|');
        }
        String result = sb.toString().trim();
        if (result.endsWith("|")) {
            result = result.substring(0, result.length() - 1).trim();
        }
        sb = new StringBuilder("^(");
        sb.append(result);
        sb.append(").*$");
        return sb.toString();
    }

    private void addFilterExp(String filterName, String expression) {
        TestDesignControllerList.newInstance().getSearchController()
                .operationAddLabelFilter(filterName, expression);
    }

    private void updateFilterExp(int id, String name, String expression) {
        TestDesignControllerList.newInstance().getSearchController()
                .operationUpdateLabelFilter(id, name, expression);
    }

    private String buildRegex(String statement) {
        StringBuilder sb = new StringBuilder();
        boolean select = true;
        if (statement.indexOf("!(") == 0) { // 'not select' statement
            select = false;
            int beginIndex = statement.indexOf('(');
            int endIndex = statement.indexOf(')');
            statement = statement.substring(beginIndex + 1, endIndex);
        }

        String[] temp = statement.split(" AND");
        for (int i = 0; i < temp.length; i++) {
            String label = temp[i].trim();
            String regex;
            if (label.indexOf('!') == 0) { // 'not select'
                regex = NOT_SELECT_LABEL_REGEX;
                regex = regex.replaceFirst("label", label.substring(1));
            } else {
                regex = SELECT_LABEL_REGEX;
                regex = regex.replaceFirst("label", label);
            }
            sb.append(regex);
        }
        if (temp.length >= 2) {
            sb = new StringBuilder("(" + sb.toString() + ")");
        }

        if (!select) {// 'not select' statement
        }

//        System.out.print(sb.toString());
        return sb.toString();
    }

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_okButtonActionPerformed
    {//GEN-HEADEREND:event_okButtonActionPerformed
        TestDesignControllerList.newInstance().getSearchController().operationClickOk();
        dispose();
    }//GEN-LAST:event_okButtonActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jCheckBox1ActionPerformed
    {//GEN-HEADEREND:event_jCheckBox1ActionPerformed
        TestDesignControllerList.newInstance().getSearchController().operationApplySelection(jCheckBox1.isSelected());
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cancelButtonActionPerformed
    {//GEN-HEADEREND:event_cancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void removeButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_removeButtonActionPerformed
    {//GEN-HEADEREND:event_removeButtonActionPerformed
        removeButton.setEnabled(false);
        ((DefaultListModel) queryItemList.getModel()).removeElementAt(queryItemList.getSelectedIndex());
    }//GEN-LAST:event_removeButtonActionPerformed

    private void queryItemListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_queryItemListValueChanged
        if (queryItemList.getSelectedValue() == null) {
            removeButton.setEnabled(false);
        } else {
            removeButton.setEnabled(true);
        }
}//GEN-LAST:event_queryItemListValueChanged

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        LinkedList<String> expList = getFilterExpList();
        String expression = buildFilterExpression(expList);
        if(expression.length() == 0){
            return;
        }
        
        DefaultComboBoxModel model = (DefaultComboBoxModel) filterComboBox.getModel();
        Object obj = model.getSelectedItem();
        if (obj != null && obj instanceof LabelFilterRefined) {
            LabelFilterRefined labelFilter = (LabelFilterRefined) obj;
            updateFilterExp(labelFilter.getId(), labelFilter.getName(), expression);
        } else {
            String filterName = JOptionPane.showInputDialog("Filter Name");
            if (filterName != null && filterName.trim().length() > 0) {
                addFilterExp(filterName, expression);
            }
        }

    }//GEN-LAST:event_saveButtonActionPerformed

    private void loadFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadFilterButtonActionPerformed
        DefaultComboBoxModel model = (DefaultComboBoxModel) filterComboBox.getModel();
        Object obj = model.getSelectedItem();
        if (obj instanceof LabelFilterRefined) {
            LabelFilterRefined labelFilter = (LabelFilterRefined) obj;
            String expression = labelFilter.getFilterExpression();
            LinkedList<String> expList = parseFilterExpression(expression);
            populateQueryItemList(expList);
        }
    }//GEN-LAST:event_loadFilterButtonActionPerformed

    @Override
    public void modelPropertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals(SearchController.TREE_LOAD)) {
            MyDefaultMutableTreeNode node = (MyDefaultMutableTreeNode) evt.getNewValue();
            loadJTestDesignTree(node, testDesignTree);
            expandAll(testDesignTree, true);
        } else if (evt.getPropertyName().equals(SearchController.TREE_REFRESH)) {
            testDesignTree.updateUI();
        } else if (evt.getPropertyName().equals(SearchController.SELECT_DESIGN_PART)) {
        } else if (evt.getPropertyName().equals(SearchController.SHOW_SELECTER)) {
            this.centerParent();
        } else if (evt.getPropertyName().equals(SearchController.PROPERTIES)) {
            propertyTextPane.setText(evt.getNewValue().toString());
            propertyTextPane.repaint();
        } else if (evt.getPropertyName().equals(SearchController.MARK_AS_SELECTED)) {
            MyDefaultMutableTreeNode node = (MyDefaultMutableTreeNode) evt.getNewValue();
            node.setSelected(true);
            node.setSelectedSingle(true);
        } else if (evt.getPropertyName().equals(SearchController.MARK_AS_UNSELECTED)) {
            MyDefaultMutableTreeNode node = (MyDefaultMutableTreeNode) evt.getNewValue();
            node.setSelected(false);
        } else if (evt.getPropertyName().equals(
                SearchController.LABEL_TREE_MODEL_PROPERTY)) {
            refreshLabelTree((DefaultTreeModel) evt.getNewValue());
        } else if (evt.getPropertyName().equals(
                SearchController.LABEL_FILTER_LIST_PROPERTY)) {
            LinkedList<LabelFilterRefined> filters = (LinkedList<LabelFilterRefined>) evt.getNewValue();
            populateFiltersCombobox(filters);
        } else if (evt.getPropertyName().equals(SearchController.ERROR_PROPERTY)) {
            String val = (String) evt.getNewValue();
            JOptionPane.showMessageDialog(
                    this,
                    val,
                    "Error Dialog",
                    JOptionPane.ERROR_MESSAGE);
        }
    }

    private void unSelectAll(MyDefaultMutableTreeNode node) {
        node.setSelected(false);
        node.setSelectedSingle(false);
        for (int i = 0; i < node.getChildCount(); i++) {
            unSelectAll(node.getChildAt(i));
        }
    }

    /* comments */
    private void loadJTestDesignTree(MyDefaultMutableTreeNode root,
            JTree jTree1) {
        MyDefaultMutableTreeNode tempNode = new MyDefaultMutableTreeNode(true);
        convert(root,
                tempNode,
                true);
        m_jDesignTreeRoot.add((MyDefaultMutableTreeNode) tempNode.getFirstChild());
        jTree1.updateUI();
    }

    private void convert(MyDefaultMutableTreeNode node,
            MyDefaultMutableTreeNode parent,
            boolean hasCheckBox) {
        TestDesignTreeNode treeNode = (TestDesignTreeNode) node.getUserObject();
        parent.add(node);
        if (treeNode.hasChildren()) {
            TestDesignTreeNode[] array = treeNode.getChildren();
            for (int i = 0; i <
                    array.length; i++) {
                convert(new MyDefaultMutableTreeNode(array[i],
                        hasCheckBox),
                        node,
                        hasCheckBox);
            }
        }
    }

    public void expandAll(JTree tree, boolean expand) {
        MyDefaultMutableTreeNode root = (MyDefaultMutableTreeNode) tree.getModel().getRoot();

        // Traverse tree from root
        expandAll(tree, new TreePath(root), expand);
    }

    private void expandAll(JTree tree, TreePath parent, boolean expand) {
        // Traverse children
        MyDefaultMutableTreeNode node = (MyDefaultMutableTreeNode) parent.getLastPathComponent();
        if (node.getChildCount() >= 0) {
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                MyDefaultMutableTreeNode n = (MyDefaultMutableTreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                expandAll(tree, path, expand);
            }

        }
        // Expansion or collapse must be done bottom-up
        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton cancelButton;
    private javax.swing.JComboBox filterComboBox;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTree labelTree;
    private javax.swing.JPanel leftPanel;
    private javax.swing.JButton loadFilterButton;
    private javax.swing.JButton okButton;
    private javax.swing.JComboBox operatorComboBox;
    private javax.swing.JTextPane propertyTextPane;
    private javax.swing.JList queryItemList;
    private javax.swing.JButton removeButton;
    private javax.swing.JPanel rightPanel;
    private javax.swing.JButton saveButton;
    private javax.swing.JButton selectButton;
    private javax.swing.JTree testDesignTree;
    // End of variables declaration//GEN-END:variables

    private void initLabelTree() {
        labelTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
//                labelTree.putClientProperty("JTree.lineStyle", "Angled");
        labelTree.setCellRenderer(new TristateLabelTreeNodeRenderer());
        labelTree.setCellEditor(new TristateLabelTreeNodeEditor(labelTree));
        labelTree.setEditable(true);
        labelTree.setExpandsSelectedPaths(false);
        labelTree.setRootVisible(false);
    }

    private void refreshLabelTree(DefaultTreeModel model) {
        labelTree.setModel(model);
        labelTree.updateUI();
        expandLabelTree();
    }

    private void expandLabelTree() {
        for (int i = 0; i <
                labelTree.getRowCount(); i++) {
            labelTree.expandRow(i);
        }
    }

    private String getLabelSelectionStr() {
        StringBuilder sb = new StringBuilder();
        LinkedList<DefaultMutableLabelNode> selectedNodes = getSelectedNodes(labelTree);
        for (int i = 0; i < selectedNodes.size(); i++) {
            Object obj = selectedNodes.get(i).getUserObject();
            if (obj != null && obj instanceof TristateLabelTreeNode) {
                TristateLabelTreeNode tristateLabel = (TristateLabelTreeNode) obj;
                T_test_label label = (T_test_label) tristateLabel.getObject();
                if (tristateLabel.getState() == TristateState.SELECTED) {
                    sb.append(" " + label.getName() + " AND");
                } else if (tristateLabel.getState() == TristateState.INDETERMINATE) {
                    sb.append(" !" + label.getName() + " AND");
                }
//                System.out.print(label.getName() + ": " + tristateLabel.getState());
            }
        }
        String result = sb.toString().trim();
        if (result.endsWith("AND")) {
            result = result.substring(0, result.length() - 3).trim();
        }
        return result;
    }

    private LinkedList<DefaultMutableLabelNode> getSelectedNodes(JTree tree) {
        LinkedList<DefaultMutableLabelNode> result = new LinkedList<DefaultMutableLabelNode>();
        javax.swing.tree.TreeModel model = tree.getModel();
        if (model != null) {
            Object root = model.getRoot();
            walkForSelectedNodes(model, root, result);
        }

        return result;
    }

    private void walkForSelectedNodes(javax.swing.tree.TreeModel model, Object o, LinkedList<DefaultMutableLabelNode> selectedNodes) {
        DefaultMutableLabelNode node = (DefaultMutableLabelNode) o;
        if (node != null) {
            TristateLabelTreeNode tristateLabel = (TristateLabelTreeNode) node.getUserObject();
            if (tristateLabel != null) {
//                System.out.println("TRISTATE LABEL\t" + tristateLabel.getName() + ": " + tristateLabel.getState().toString());
                TristateState tristate = tristateLabel.getState();
                if (tristate == TristateState.SELECTED || tristate == TristateState.INDETERMINATE) {
                    selectedNodes.add(node);
                }

            }
            if (!model.isLeaf(o)) {
                int cc = model.getChildCount(o);
                for (int i = 0; i <
                        cc; i++) {
                    Object child = model.getChild(o, i);
                    walkForSelectedNodes(model, child, selectedNodes);
                }
            }
        }
    }

    private LinkedList<String> getFilterExpList() {
        LinkedList<String> result = new LinkedList<String>();
        for (int i = 0; i < queryItemList.getModel().getSize(); i++) {
            result.add((String) queryItemList.getModel().getElementAt(i));
        }
        return result;
    }

    private void populateQueryItemList(LinkedList<String> list) {
        if (list == null) {
            return;
        }
        DefaultListModel model = (DefaultListModel) queryItemList.getModel();
        model.clear();
        for (int i = 0; i < list.size(); i++) {
            model.addElement(list.get(i));
        }
    }

    private void populateFiltersCombobox(LinkedList<LabelFilterRefined> list) {
        if (list == null) {
            return;
        }
        DefaultComboBoxModel model = (DefaultComboBoxModel) filterComboBox.getModel();
        model.removeAllElements();
        model.addElement(new String(""));
        for (int i = 0; i < list.size(); i++) {
            model.addElement(list.get(i));
        }
    }

    private LinkedList<String> parseFilterExpression(String expression) {
        LinkedList<String> result = new LinkedList<String>();
        String[] split = expression.split("_#_");
        for (int i = 0; i < split.length; i++) {
            if (split[i].trim().length() > 0) {
                result.add(split[i].trim());
            }
        }
        return result;
    }

    private String buildFilterExpression(LinkedList<String> expList) {
        StringBuilder sb = new StringBuilder();
        if (expList != null) {
            for (int i = 0; i < expList.size(); i++) {
                if (i == 0) {
                    sb.append(expList.get(i));
                } else {
                    sb.append("_#_" + expList.get(i));
                }
            }
        }
        return sb.toString();
    }
}
